//functions.cpp
/********************************************************************************
*																				*
*	Author:			Jared Szechy												*
*	Assignment:		Assignment 3												*
*	Class:			CPS-151														*
*	Instructor:		V. Starkley													*
*	Due Date:		September 20												*
*																				*
*	This file implements the the applications functions.						*
*																				*
********************************************************************************/
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;

#include "functions.h"

void readAccounts(istream& fin, SortedType& accounts)
{
	BankAccount tempAccount;
	string tempString;
	double tempDouble;

		while(isspace(fin.peek()))
			fin.ignore();
		getline(fin, tempString, ',');

		tempAccount.setLastName(tempString);

		fin >> tempString;

		tempAccount.setFirstName(tempString);

		fin >> tempString;

		tempAccount.setAccountNumber(tempString);

		fin >> tempDouble;

		tempAccount.setAccountBalance(tempDouble);

	while (!fin.fail() && accounts.LengthIs() < MAX_ITEMS)
	{
		accounts.InsertItem(tempAccount);

		while(isspace(fin.peek()))
			fin.ignore();
		getline(fin, tempString, ',');

		tempAccount.setLastName(tempString);
	
		fin >> tempString;

		tempAccount.setFirstName(tempString);

		fin >> tempString;

		tempAccount.setAccountNumber(tempString);

		fin >> tempDouble;

		tempAccount.setAccountBalance(tempDouble);
	}
}

void printMenu()
{
	cout << endl;
	cout << setw(6) << "(1)" << '\t' << "Add a new account" << endl;
	cout << setw(6) << "(2)" << '\t' << "Delete an account" << endl;
	cout << setw(6) << "(3)" << '\t' << "Change the name of the account holder" << endl;
	cout << setw(6) << "(4)" << '\t' << "Make a deposit" << endl;
	cout << setw(6) << "(5)" << '\t' << "Make a withdrawal" << endl;
	cout << setw(6) << "(6)" << '\t' << "Display information for a specific account" << endl;
	cout << setw(6) << "(7)" << '\t' << "Display information for all accounts" << endl;
	cout << setw(6) << "(8)" << '\t' << "Write all account information to a file" << endl;
	cout << setw(6) << "(9)" << '\t' << "Quit the program" << endl;
	cout << endl << "Selection: ";
}

void processSelection(int selection, SortedType& accounts)
{
	switch (selection)
	{
	case 1:
		//Add a new account
		if(addAccount(accounts))
			cout << endl << "Account added!" << endl << endl;
		else
			cout << endl << "Could not add account!" << endl << endl;
		break;
	case 2:
		//Delete an account
		if(deleteAccount(accounts))
			cout << endl << "Account deleted!" << endl << endl;
		else
			cout << endl << "Could not delete account! Check account number." << endl << endl;
		break;
	case 3:
		//Change the name of the account holder
		if(changeName(accounts))
			cout << endl << "Name Changed!" << endl << endl;
		else
			cout << endl << "Could not change name! Check account number." << endl << endl;
		break;
	case 4:
		//Make a deposit
		if(depositFunds(accounts))
			cout << endl << "Transaction complete!" << endl << endl;
		else
			cout << endl << "Could not deposit funds! Check account number." << endl << endl;
		break;
	case 5:
		//Make a withdrawal
		if(withdrawlFunds(accounts))
			cout << endl << "Transaction complete!" << endl << endl;
		else
			cout << endl << "Could not withdrawl funds! Check account number." << endl << endl;
		break;
	case 6:
		//Display information for a specific account
		if(!printAccount(accounts))
			cout << endl << "Could find account! Check account number." << endl << endl;
		break;
	case 7:
		//Display information for all accounts
		printAll(accounts);
		break;
	case 8:
		//Write all account information to a file
		if(writeFile(accounts))
			cout << endl << "Accounts written to file." << endl << endl;
		else
			cout << endl << "Could not write accounts to file." << endl << endl;
		break;
	case 9:
		//Quit the program
		exit(0);
		break;
	default:
		cout << endl << "Invalid Selection" << endl << endl;
		break;
	}
}

void printAll(SortedType accounts)
{
	BankAccount tempAccount;
	accounts.ResetList();

	cout << setw(12) << "Name" << setw(25) << "Account Number" << setw(11) << "Balance" << endl;
	cout << "------------------------------------------------" << endl;

	for (int i = 0; i < accounts.LengthIs(); i++)
	{
		accounts.GetNextItem(tempAccount);

		cout << setw(10) << tempAccount.getLastName() << ", " << tempAccount.getFirstName()
			 << setw(16) << tempAccount.getAccountNumber() << setw(14) 
			 << tempAccount.getAccountBalance() << endl;
	}
}

bool addAccount(SortedType& accounts)
{
	if (accounts.LengthIs() >= MAX_ITEMS)
		return false;
	else
	{
		string lastName, firstName;
		string account;
		double balance;
		BankAccount tempAccount;

		cout << "Enter user information." << endl;
		cout << "Last name: ";
		cin >> lastName;
		cout << "First name: ";
		cin >> firstName;
		cout << "Account number: ";
		cin >> account;
		cout << "Opening balance: $";
		cin >> balance;
		
		tempAccount.setLastName(lastName);
		tempAccount.setFirstName(firstName);
		tempAccount.setAccountNumber(account);
		tempAccount.setAccountBalance(balance);

		accounts.InsertItem(tempAccount);

		return true;
	}
}

bool deleteAccount(SortedType& accounts)
{
	string accountNumber;
	BankAccount tempAccount;

	cout << "Enter the account number: ";
	cin >> accountNumber;

	tempAccount.setAccountNumber(accountNumber);

	if(accounts.DeleteItem(tempAccount))
		return true;
	else
		return false;
}

bool changeName(SortedType& accounts)
{
	string accountNumber;
	string firstName, lastName;
	BankAccount tempAccount;

	cout << "Enter the account number: ";
	cin >> accountNumber;

	tempAccount.setAccountNumber(accountNumber);

	if(!accounts.RetrieveItem(tempAccount))
		return false;

	cout << endl;
	cout << tempAccount.getLastName() << ", " << tempAccount.getFirstName() << endl;
	cout << tempAccount.getAccountNumber() << endl;
	cout << '$' << tempAccount.getAccountBalance() << endl << endl;

	cout << "Enter new name below." << endl;
	cout << "Last name :";
	cin >> lastName;
	cout << "First name :";
	cin >> firstName;

	tempAccount.setLastName(lastName);
	tempAccount.setFirstName(firstName);

	if (accounts.DeleteItem(tempAccount) && accounts.InsertItem(tempAccount))
		return true;
	else
		return false;
}

bool depositFunds(SortedType& accounts)
{
	string accountNumber;
	double deposit;
	BankAccount tempAccount;

	cout << "Enter the account number: ";
	cin >> accountNumber;

	tempAccount.setAccountNumber(accountNumber);
		
	if(!accounts.RetrieveItem(tempAccount))
		return 0;

	cout << "Enter deposit amount: $";
	cin >> deposit;

	tempAccount.setAccountBalance(tempAccount.getAccountBalance() + deposit);

	if (accounts.DeleteItem(tempAccount) && accounts.InsertItem(tempAccount))
		return true;
	else
		return false;
}

bool withdrawlFunds(SortedType& accounts)
{
	string accountNumber;
	double withdrawl;
	BankAccount tempAccount;

	cout << "Enter the account number: ";
	cin >> accountNumber;

	tempAccount.setAccountNumber(accountNumber);
		
	if(!accounts.RetrieveItem(tempAccount))
		return 0;

	cout << "Enter withdrawl amount: $";
	cin >> withdrawl;

	if (withdrawl > tempAccount.getAccountBalance())
	{
		cout << endl << "Insufficient funds: transaction cancelled" << endl;
		return false;
	}

	tempAccount.setAccountBalance(tempAccount.getAccountBalance() - withdrawl);

	if (accounts.DeleteItem(tempAccount) && accounts.InsertItem(tempAccount))
		return true;
	else
		return false;
}

bool printAccount(SortedType& accounts)
{
	string accountNumber;
	BankAccount tempAccount;

	cout << "Enter the account number: ";
	cin >> accountNumber;

	tempAccount.setAccountNumber(accountNumber);

	if(!accounts.RetrieveItem(tempAccount))
		return false;

	cout << endl;
	cout << tempAccount.getLastName() << ", " << tempAccount.getFirstName() << endl;
	cout << "Account Number: " << tempAccount.getAccountNumber() << endl;
	cout << "Account Balance: " << '$' << tempAccount.getAccountBalance() << endl << endl;

	return true;
}

bool writeFile(SortedType accounts)
{
	BankAccount tempAccount;
	ofstream fout;
	accounts.ResetList();

	fout.open("bankAccounts.txt");
	if(fout.fail())
		return false;


	for (int i = 0; i < accounts.LengthIs(); i++)
	{
		accounts.GetNextItem(tempAccount);

		fout << tempAccount.getLastName() << ", " << tempAccount.getFirstName()
			 << '\t' << tempAccount.getAccountNumber() << '\t' 
			 << tempAccount.getAccountBalance() << endl;
	}

	return true;
}